package Client;

import java.util.ArrayList;

import Messages.Msg;
import Messages.StopMsg;

/**
 * responsible for running the client protocol.
 * the manager holds a queue of messages to be send to client.
 * all who want to send messages, add message to manager
 * @author liel && guy
 *
 */
public class Manager implements Runnable{
	ClientProtocol clientProtocol;
	ArrayList<Msg> msgToServer;
	ClientDetails clientDetails;
	Msg msg;
	
	private static class Holder{
		volatile static Manager managerSingeltin=new Manager();
	}
	
	private Manager(){
		msgToServer = new ArrayList<Msg>();
		clientProtocol = null;
		
	}
	/**
	 * receive the instance of the manager
	 * @return the instance of the manager
	 */
	public static Manager getInstance(){
		return Holder.managerSingeltin;
	}
	/**
	 * set client details
	 * @param cd - the client details
	 */
	public void setClientDetails(ClientDetails cd){
		clientDetails = cd;
		this.clientProtocol = new ClientProtocol(clientDetails);
	}
	
	/**
	 * add message to queue
	 * @param msg - the message we want to add
	 */
	public void addMsg(Msg msg){
		synchronized (this) {
			msgToServer.add(msg);
			notify();
		}
		System.out.println("end sync in add");
	}
	
	/**
	 * get message from queue
	 * @return the message in the top of the queue
	 */
	public Msg getMsg(){
		Msg msg;
		synchronized (this) {
			if (msgToServer.size()==0){
				System.out.println("size 0 in get");
				msg = new StopMsg();
			}
			else{
				System.out.println("else in get");
				msg = msgToServer.get(0);
				msgToServer.remove(0);
			}
		}
		return msg;
	}
	
	/**
	 * rum this loop for ever, this is where the protocol is running
	 */
	@Override
	public void run() {
		while (true){
			System.out.println("in run 1 before sync");
			synchronized (this) {
				System.out.println("in run 1 after sync");
				if (msgToServer.size()==0)
				{
					try {
						System.out.println("going to wait");
						this.wait();
						System.out.println("after wait");
						
					} catch (InterruptedException e) {
						System.out.println("size is "+msgToServer.size());		
					}
				}
			} //end sync
				
			try {
				Thread.sleep(250);
			} catch (InterruptedException e) {
				e.printStackTrace();
		    }
			clientProtocol.run();
		} //end while
	}
}
